import { WebAudioFontPlayer } from "../../utils/WebAudioFontPlayer";
import { _tone_0255_GeneralUserGS_sf2_file } from "../../utils/0255_GeneralUserGS_sf2_file";
import defaultOptionList from "../../utils/defaultOptionList";

const TIME_RATE = 0.2;

// 7音
const note = [0, 2, 4, 5, 7, 9, 11];
// 八个层级
const levels = [
  3,
  4,
  5, //0,1,2,3,4,5,6,7
];
let actx = wx.createWebAudioContext();
let player = new WebAudioFontPlayer();
player.adjustPreset(actx, _tone_0255_GeneralUserGS_sf2_file);

Page<
  {
    type: string;
    pai: string;
    mode: number;
    currentChar: string;
    editting: boolean;
    musicIndex: number;
    scrollPoint: string;
    optionsList: IJiaPuPption[];
  },
  any
>({
  data: {
    type: "1", // 声音类型
    pai: "2", // 声音节拍长度
    mode: 0, // 自由模式0 简单模式1 灵魂模式2 自动播放3
    currentChar: "", // 当前高亮的音符
    editting: false,
    musicIndex: 0, // 乐谱滚动到的简谱序号
    scrollPoint: "music_start", //乐谱滚动到哪里
    optionsList: [{ char: "6", level: 1, pai: 1, split: false }], // 数据源
  },
  onShow() {
    const info = wx.getStorageSync("JP_INFO");
    if (info) {
      this.setData({
        optionsList: JSON.parse(info),
      });
    } else {
      this.setData({
        optionsList: defaultOptionList,
      });
    }

    actx = wx.createWebAudioContext();
    player = new WebAudioFontPlayer();
    player.adjustPreset(actx, _tone_0255_GeneralUserGS_sf2_file);
  },
  // 根据音高，音符，节拍来播放音乐
  playMusic(type, char, pai, time = 0) {
    if (char === "0") {
      return;
    }
    const pitch = levels[type] * 12 + note[char - 1];
    player.queueWaveTable(
      actx,
      actx.destination,
      _tone_0255_GeneralUserGS_sf2_file,
      time,
      pitch,
      TIME_RATE * parseFloat(pai),
      1
    );
  },
  playMusicNext() {
    let newMusicIndex = this.data.musicIndex + 1;
    if (newMusicIndex >= this.data.optionsList.length) {
      newMusicIndex = 0;
    }
    const currentOption = this.data.optionsList[this.data.musicIndex];
    this.setData(
      {
        pai: currentOption.pai.toString(),
        type: currentOption.level.toString(),
        musicIndex: newMusicIndex,
        scrollPoint: `music_${newMusicIndex}`,
        currentChar: currentOption.char,
      },
      () => {
        if (this.data.mode === 3) {
          this.playMusic(this.data.type, currentOption.char, this.data.pai);
          setTimeout(() => {
            this.playMusicNext();
          }, parseFloat(this.data.pai) * TIME_RATE * 1000);
        } else {
          this.setData({
            currentChar: "",
          });
        }
      }
    );
  },
  // 跳转教程页面
  handleGoTutorial() {
    wx.navigateTo({
      url: "/pages/tutorial/tutorial",
    });
  },
  // 切换模式
  tapSwitchMode() {
    let newMode = this.data.mode + 1;
    if (newMode > 3) {
      newMode = 0;
    }
    this.setData({
      mode: newMode,
      musicIndex: 0,
      scrollPoint: `music_start`,
    });
    // 切换到自动模式自动播放
    if (newMode === 3) {
      this.playMusicNext();

      // 以下模式是另一种自动模式实现方案，可以解决在真机上的延迟问题，但是杂音严重。
      // let currentTime = 3;

      // for (let i = 0, len = this.data.optionsList.length; i < len; i++) {
      //   const currentOption = this.data.optionsList[i];
      //   if (currentOption.char === "0") {
      //     continue;
      //   }

      //   const pitch =
      //     levels[currentOption.level] * 12 + note[currentOption.char - 1];
      //   player.queueWaveTable(
      //     actx,
      //     actx.destination,
      //     _tone_0255_GeneralUserGS_sf2_file,
      //     currentTime,
      //     pitch,
      //     TIME_RATE * parseFloat(currentOption.pai),
      //     1
      //   );
      //   const duration = parseFloat(currentOption.pai) * TIME_RATE;
      //   currentTime += duration;
      // }
    }
  },
  tapTimeKey(e: any) {
    this.setData({
      pai: e.target.dataset.key,
    });
  },
  // 点击分隔符
  tapSplit() {
    if (this.data.editting && this.data.optionsList.length > 0) {
      this.data.optionsList[this.data.optionsList.length - 1].split = true;
      this.setData({
        optionsList: this.data.optionsList,
      });
      return;
    }
  },
  // 点击音符
  tapMainKey(e: any) {
    if (this.data.editting) {
      this.data.optionsList.push({
        char: e.currentTarget.dataset.key,
        level: Number.parseInt(this.data.type),
        pai: Number.parseFloat(this.data.pai),
      });
      const newIndex = this.data.optionsList.length - 1;
      this.setData({
        musicIndex: newIndex,
        scrollPoint: `music_${newIndex}`,
        optionsList: this.data.optionsList,
      });
      return;
    }
    let newMusicIndex = this.data.musicIndex + 1;
    if (newMusicIndex >= this.data.optionsList.length) {
      newMusicIndex = 0;
    }
    if (this.data.mode === 0) {
      // 自由模式
      this.playMusic(
        this.data.type,
        e.currentTarget.dataset.key,
        this.data.pai
      );
      this.setData({
        musicIndex: newMusicIndex,
        scrollPoint: `music_${newMusicIndex}`,
      });
    } else if (this.data.mode === 1) {
      // 简单模式
      const currentOption = this.data.optionsList[this.data.musicIndex];
      this.setData(
        {
          pai: currentOption.pai.toString(),
          type: currentOption.level.toString(),
          musicIndex: newMusicIndex,
          scrollPoint: `music_${newMusicIndex}`,
        },
        () => {
          this.playMusic(
            this.data.type,
            e.currentTarget.dataset.key,
            this.data.pai
          );
        }
      );
    } else {
      // 灵魂模式
      const currentOption = this.data.optionsList[this.data.musicIndex];
      this.setData(
        {
          pai: currentOption.pai.toString(),
          type: currentOption.level.toString(),
          musicIndex: newMusicIndex,
          scrollPoint: `music_${newMusicIndex}`,
        },
        () => {
          this.playMusic(this.data.type, currentOption.char, this.data.pai);
        }
      );
    }
  },
  tapAssistKey(e: any) {
    this.setData({
      type: e.target.dataset.key,
    });
  },
  // 进入编辑状态
  handleEdit() {
    this.setData({
      editting: true,
      musicIndex: this.data.optionsList.length - 1,
      scrollPoint: "music_end",
      mode: 0,
      type: "1",
      pai: "2",
    });
  },
  // 退出编辑状态
  handleExitEdit() {
    this.setData({
      editting: false,
      musicIndex: 0,
      scrollPoint: "music_start",
      mode: 0,
      type: "1",
      pai: "2",
    });
    wx.setStorageSync("JP_INFO", JSON.stringify(this.data.optionsList));
  },
  // 删除
  handleDelete() {
    this.data.optionsList.pop();
    const newIndex = this.data.optionsList.length - 1;
    this.setData({
      musicIndex: newIndex,
      scrollPoint: `music_${newIndex}`,
      optionsList: this.data.optionsList,
    });
  },
  onHide() {
    this.setData({
      editting: false,
      musicIndex: 0,
      scrollPoint: "music_start",
      mode: 0,
      type: "1",
      pai: "2",
    });
  },
});
